home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / dspdsk3 / mdm_drv2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-24  |  17.9 KB  |  520 lines

  1. /************************************************
  2.  TMS320C26 DSK RS232 I/O AND OTHER ASSORTED FUNCTIONS
  3.  Keith Larson
  4.  DSP Applications
  5.  Texas Instruments Inc
  6.  (C)opyright 1992, 1993
  7.  ************************************************/
  8. #include <stdlib.h>
  9. #include <bios.h>
  10. #include <ctype.h>
  11. #include <conio.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <graphics.h>
  15. #include <dos.h>
  16.  
  17. #include "DSK_DRV2.H"
  18.  
  19. extern int port_no;
  20. extern int baud, userbaud;
  21.  
  22. int start_graphics(void)
  23. {
  24.   int gdriver = EGA, gmode = EGAHI, errorcode;
  25. //  registerbgidriver(EGAVGA_driver);
  26.   initgraph(&gdriver, &gmode, "");
  27.   errorcode = graphresult();
  28.   if (errorcode != grOk)
  29.   {
  30.      printf("Graphics error: %s\n", grapherrormsg(errorcode));
  31.      printf("Press any key to halt:");
  32.      getch();
  33.      exit(1);
  34.   }
  35.   setviewport(100, 50, 355, 305, 1);
  36.   return 0;
  37. }
  38.  
  39. void GRAPH(void)
  40. {
  41.   int x, y, page=0;
  42.   char ch;
  43.   start_graphics();
  44.   for(;;)
  45.   {
  46.     ch = crcv(port_no);
  47.     y = ch;
  48.     if(y == 0)
  49.     {
  50.       setvisualpage(page);
  51.       page ^= 1;
  52.       setactivepage(page);
  53.       cleardevice();
  54.       rectangle(0,0,255,255);
  55.       moveto(0,255);
  56.       x = 0;
  57.     }
  58.     y = 128 - y;
  59.     lineto(x,y);
  60.     x++;
  61.     if(kbhit())
  62.     {
  63.       closegraph();
  64.       clrscr();
  65.       printf(">>>>>> DSKL is now in command mode\n");
  66.       return;
  67.     }
  68.   }
  69. }
  70.  
  71. void execute(int addr)
  72. {
  73.   cxmit(SYNCH,port_no);
  74.   cxmit(BRANCH,port_no);                // Select BRANCH to address
  75.   ixmit(addr,port_no);
  76. }
  77.  
  78. void usage(void)
  79. {
  80. printf("DSKL:  DOS Command line Usage                                    \n");
  81. printf("                                                                 \n");
  82. printf("C:\DSKTOOLS\DSKL [A][Cx][Bxxxxx][I]                              \n");
  83. printf("                  |   |   |      |                               \n");
  84. printf("                  |   |   |      +--Inverse DTR (Reset logic)    \n");
  85. printf("                  |   |   +---------Baud xxxxx (9600,19200,38400)\n");
  86. printf("                  |   +-------------Initialy load to COM1, COM2  \n");
  87. printf("                  +-----------------Autotest                     \n");
  88. printf("                                                                 \n");
  89. printf("NOTE:                                                            \n");
  90. printf("  Up & Down adjusts baud                                         \n");
  91. printf("  Left & Right changes commport                                  \n");
  92. printf("  Q will quit during bootload                                    \n");
  93. printf("                                                                 \n");
  94. }
  95.  
  96. /*********************************************************************/
  97. /* unsigned int load_file(int arg, char *FILE)                       */
  98. /* if arg = 0; MDM_COM2.DSK is bootloaded and verified (echo data)   */
  99. /*          1; INFILE.DSK is requested and loaded via MDM_COM2.DSK   */
  100. /*          2; FILE is loaded via MDM_COM2.DSK                       */
  101. /*                                                                   */
  102. /* Returns the file ENTRY point                                      */
  103. /*********************************************************************/
  104. unsigned int load_file(int arg, char *strg)
  105. {
  106.   char fbuf[32], key;
  107.   int TEST;
  108.   uint ENTRY, i, tries = 1;
  109.   ulong rate;
  110.   strcpy(fbuf,"MDM_COM2.DSK");
  111.  
  112.   i = 2 -((port_no-0x2f8) >> 8);
  113.   switch(arg)
  114.   {
  115.   case 3: printf(" FILE TO BOOT >> ");
  116.           strupr(gets(fbuf));
  117.           if(strstr(fbuf,".") == NULL) strcat(fbuf,".DSK");
  118.           arg = 0;
  119.  
  120.   case 0: TEST = 0;
  121.           while(TEST != 0x1111)
  122.           {
  123.             clrscr();
  124.             i = 2 -((port_no-0x2f8) >> 8);
  125.             rate = 115200/baud;
  126.             printf("[Q]uit exits program\n\n");
  127.             printf("%s >Boot:%d  Com:%d  Baud:%lu\n",fbuf,tries++,i,rate);
  128.             baud = baud << 2;                // kernal loads at 1/4 baud
  129.             ENTRY = load_DSK(arg,fbuf);
  130.             baud = baud >> 2;                // set original baud 4x
  131.             initcom(port_no,baud);
  132.             if(kbhit())
  133.             {
  134.               i = bioskey(0);
  135.               key = i & 0xff;
  136.               if((key == 'Q') || (key == 'q')) exit(0);
  137.               if(i==0x4B00) port_no = 0x3f8;
  138.               if(i==0x4D00) port_no = 0x2f8;
  139.               if(i==0x4800) baud = baud >> 1;
  140.               if(i==0x5000) baud = baud << 1;
  141.               if(baud == 0) baud = 1;
  142.               if(baud > 96) baud = 96;
  143.             }
  144.             TEST = 0x1111;
  145.             write_data(0x70,1,&TEST);        // write and verify a
  146.             TEST = 0;                        // known value to the DSK
  147.             read_data (0x70,1,&TEST);
  148.           }
  149.           TEST = 0;
  150.           write_data(0x70,1,&TEST);
  151.           printf("%s Succesfully loaded\n",fbuf);
  152.           break;
  153.  
  154.   case 1: printf(" FILE TO LOAD >> ");
  155.           strupr(gets(fbuf));
  156.           if(strstr(fbuf,".") == NULL) strcat(fbuf,".DSK");
  157.           printf("Loading %s to DSK Com:%d\n",fbuf,i);
  158.           ENTRY = load_DSK(arg,fbuf);
  159.           break;
  160.  
  161.   case 2: arg = 1;
  162.           strupr(strg);
  163.           printf("Loading %s to DSK Com:%d\n",strg,i);
  164.           ENTRY = load_DSK(arg,strg);
  165.           break;
  166.  
  167.   default: break;
  168.   }
  169.   printf("Entry:%04x\n",ENTRY);
  170.   printf("Hit >enter< to continue\n");
  171.   return(ENTRY);
  172. }
  173. /*********************************************************************/
  174. /* unsigned int load_DSK(FILE *in_file, int pass)                    */
  175. /* if pass = 0; in_file is loaded via the C26 bootloader             */
  176. /*    pass = 1; in_file is loaded via MDM_COM2 (must be loaded!)     */
  177. /*                                                                   */
  178. /* Returns file ENTRY point                                          */
  179. /*********************************************************************/
  180. unsigned int load_DSK(int pass, char *filename)
  181. {
  182.   FILE *in_file;
  183.   char buf[512],*ptr;
  184.   unsigned int i, ENTRY,load;
  185.   int ADDR, CMD;
  186.   int boot_csum, boot_len=0;
  187.  
  188.   if ((in_file = fopen(filename, "r")) == NULL)        // Is file available?
  189.   {
  190.     printf("Could not open %s! Exiting program\n",filename);
  191.     exit(0);
  192.   }
  193.  
  194.   if(pass == 0)
  195.   {
  196.     initcom(port_no,baud);
  197.     reset(port_no);
  198.   }
  199.   pass &=0x1;
  200.   load = pass;
  201.   fseek(in_file,0,SEEK_SET);               // reset to first line
  202.   fscanf(in_file,"%s",&buf);               // Read first line
  203.   if(buf[0] != 'K')
  204.   {
  205.     printf("Not a valid DSK file\n");
  206.     getch();
  207.     fclose(in_file);
  208.     return(0);
  209.   }
  210.   for(;pass<2;pass++)
  211.   {
  212.     boot_csum= 0;
  213.     fseek(in_file,0,SEEK_SET);               // reset to first line
  214.     fscanf(in_file,"%s",&buf);               // Read first line
  215.     if((pass==1) && !load)
  216.     {
  217.       boot_len--;
  218.       ixmit((boot_len & 0x700)|0x8FF,port_no);   // STATUS and BAUD_DTCT
  219.       ixmit(((boot_len & 0xFF)<<8)|0x80,port_no);// LENGTH and INT
  220.       boot_len=0;
  221.     }
  222.     while(!feof(in_file))
  223.     {
  224.       fscanf(in_file,"%s\r\n",buf);                // Read a line
  225.       ptr = buf;
  226.       switch(buf[0])
  227.       {
  228.         case '1': ENTRY = read4(ptr);              // 1=entry point
  229.                   break;
  230.         case '9': ADDR = read4(ptr);               // 9=address
  231.                   if(load)
  232.                   {
  233.                     while(buf[0] != '7')
  234.                     {
  235.                       if(buf[0] == 'M')
  236.                         CMD = UL_DATA;
  237.                       else
  238.                       {
  239.                         if(buf[0] == 'B')
  240.                           CMD = UL_PROG;
  241.                         else
  242.                         {
  243.                           printf("ERROR READING FILE\n");
  244.                           exit(0);
  245.                         }
  246.                       }
  247.                       i = read4(ptr);
  248.                       cxmit(CMD,port_no);         // Select PROG/DATA
  249.                       ixmit(ADDR++,port_no);      // where to put it
  250.                       ixmit(0,port_no);           // length 1
  251.                       ixmit(i,port_no);           // send the value
  252.                       printf("\r%d words",boot_len++);
  253.                     }
  254.                   }
  255.                   else  /* boot */
  256.                   {
  257.                     while(buf[0] != '7')
  258.                     {
  259.                       i = read4(ptr);
  260.                       if(pass==1)
  261.                         ixmit(i,port_no);
  262.                       printf("\r%d words",boot_len);
  263.                       boot_len++;
  264.                       boot_csum += i;
  265.                     }
  266.                   }
  267.                   break;
  268.         case ':': break;
  269.         default : printf("Error reading file\n");
  270.                   ENTRY=0;
  271.                   break;
  272.       }
  273.       if(buf[0]==':') break;
  274.     }
  275.     if((pass==1) && !load)
  276.     {
  277.       ixmit(boot_csum,port_no);                     // CHECKSUM at EO 2nd pass
  278.       cxmit(0xff,port_no);                          // same for synch
  279.     }
  280.   }
  281.   printf("\n");
  282.   fclose(in_file);                        // close file when done
  283.   return(ENTRY);
  284. }
  285.  
  286. unsigned int read4(char *ptr)
  287. {
  288.   char val[200], *nptr;
  289.   unsigned int i;
  290.   strcpy(val,"0x");
  291.   strcat(val,ptr+1);
  292.   val[6] = 0;
  293.   i = strtol(val,&nptr,16);
  294.   strcpy(ptr,ptr+5);
  295.   return(i);
  296. }
  297.  
  298. /*********************************************************************/
  299. /* write_data(int address, int length, int *data);                   */
  300. /*   if MDM_COM2 is loaded, *data is transferred to the DSK          */
  301. /*********************************************************************/
  302. void write_data(int addr, int length, int *data)
  303. {
  304.   cxmit(UL_DATA,port_no);     // Select DATA download to DSK
  305.   ixmit(addr,port_no);        // where to put it
  306.   ixmit(length-1,port_no);    // length
  307.   for(;length>0;length--)     //
  308.     ixmit(*data++,port_no);   // send the value
  309. }
  310. /*********************************************************************/
  311. /*  rcv_char_buf(int length, char *data);  SPECIAL TO DSK_SA26       */
  312. /*    This routine is designed to receive a block of BYTES not int's */
  313. /*  from the DSK.  Normaly the MDM_COM2 kenral is used to transfer   */
  314. /*  blocks of integers which are the native format for the C26 DSP.  */
  315. /*  In this case rcv_char_buf is used to speed up transfers since    */
  316. /*  the result in this application is packed bytes of data which     */
  317. /*  have also been bit-reversed.  A host would be inefficient in     */
  318. /*  this task and is avoided for the sake of speed.                  */
  319. /*      ALSO PLEASE NOTE THIS MAY CHANGE IN FUTURE ANALYZERS!        */
  320. /*********************************************************************/
  321. void rcv_char_buf(int length,char *ptr)
  322. {
  323.   int x;
  324.   asm  cli                              // disable x86 INT's
  325.   cxmit(0,port_no);                     //start data sweep
  326.   for(x=0;x<length;x++)                 //
  327.     *ptr++ = Bcrcv(port_no);            // receive BYTES not INTS
  328.   asm  sti                              // enable x86 INT's
  329. }
  330. /*********************************************************************/
  331. /* read_data(int address, int length, int *data);                    */
  332. /*   if MDM_COM2 is loaded, *data is filled with data from the DSK   */
  333. /*********************************************************************/
  334. void read_data(int addr, int length, int *data)
  335. {
  336.   int i;
  337.   cxmit(DL_DATA,port_no);     // Select DATA upload from DSK
  338.   ixmit(addr,port_no);        // where to get it
  339.   ixmit(length-1,port_no);    // length
  340.   for(;length>0;length--)     //
  341.   {
  342.     // *data++ = ircv(port_no);  // receive the value
  343.     i = crcv(port_no);
  344.     i+= (crcv(port_no)<<8);
  345.     *data++ = i;
  346.   }
  347.   cxmit(SYNCH   ,port_no);    // Extra SYNCH to get back to command mode
  348. }
  349.  
  350. /*********************************************************************/
  351. /* Bread_data(int address, int length, int *data);                   */
  352. /*   Fast version of read_data where handshaking each byte is avoided*/
  353. /*   NOTE: If the host receives an interrupt etc... DANGEROUS!!!     */
  354. /*********************************************************************/
  355. void Bread_data(int addr, int length, int *data)
  356. {
  357.   int i;
  358.   asm  cli                    // turn off x86 interrupts
  359.   cxmit(BDL_DATA,port_no);    // Select DATA upload from DSK
  360.   ixmit(addr,port_no);        // where to get it
  361.   ixmit(length-1,port_no);    // length
  362.   for(;length>0;length--)     // write this routine fast!
  363.   {
  364.     i = Bcrcv(port_no);
  365.     i+= (Bcrcv(port_no)<<8);
  366.     *data++ = i;
  367.   }
  368.   cxmit(SYNCH   ,port_no);    // Extra SYNCH to get back to command mode
  369.   asm  sti                    // turn on x86 interrupts
  370. }
  371.  
  372. void initcom(int port_no,int baud)
  373. {
  374.   asm  mov  DX,word ptr port_no  //
  375.   asm  add  DX,3                 //
  376.   asm  mov  AL,087h              // set access to BAUD divisor
  377.   asm  out  DX,AL                //
  378.   asm  sub  DX,3                 //
  379.   asm  mov  AX,word ptr baud     // Set baud rate LSB
  380.   asm  out  DX,AL                //
  381.   asm  add  DX,1                 //
  382.   asm  mov  AL,byte ptr baud     // Set baud rate MSB
  383.   asm  xchg AL,AH                //
  384.   asm  out  DX,AL                //
  385.   asm  sub  DX,1                 //
  386.   asm  add  DX,3                 //
  387.   asm  mov  AL,07h               // CLR BAUD access...  N-8-2
  388.   asm  out  DX,AL                //
  389.   asm  out  DX,AL                // N-8-2
  390. }
  391.  
  392. void reset(int port_no)
  393. {
  394.   DTR_hi(port_no);
  395.   DTR_lo(port_no);
  396.   DTR_hi(port_no);
  397. }
  398. void DTR_lo(int port_no)
  399. {
  400.   asm  mov  DX,word ptr port_no //modem control register 02FCh 03FCh
  401.   asm  add  DX,4                //
  402.   asm  mov  AL,0xA              //RTS=1, DTR=0
  403.   asm  out  DX,AL               //
  404.   delay(1);
  405. }
  406. void DTR_hi(int port_no)
  407. {
  408.   asm  mov  DX,word ptr port_no //modem control register
  409.   asm  add  DX,4                //
  410.   asm  mov  AL,0xB              //RTS=1, DTR=0
  411.   asm  out  DX,AL               //
  412.   delay(1);
  413. }
  414.  
  415. void ixmit(int i,int port_no)
  416. {
  417.   cxmit(i,port_no);
  418.   cxmit(i>>8,port_no);
  419. }
  420. /****************************************************************/
  421. /* ircv and Bircv each receive two bytes making an int.         */
  422. /* NOTE: Birecv uses Bcrcv() which does not use hanshaking.     */
  423. /*       Use Bircv with caution as system ints etc.. cause pblms*/
  424. /****************************************************************/
  425. unsigned int ircv(int port_no)
  426. {
  427.   int i;
  428.   i = crcv(port_no);
  429.   i+= (crcv(port_no)<<8);
  430.   return(i);
  431. }
  432. unsigned int Bircv(int port_no)
  433. {
  434.   int i;
  435.   i = Bcrcv(port_no);
  436.   i+= (Bcrcv(port_no)<<8);
  437.   return(i);
  438. }
  439. /****************************************************************/
  440. /* cxmit transmits a charcter                                   */
  441. /****************************************************************/
  442. void cxmit(char c, int port_no)
  443. {
  444.   asm  mov  DX,word ptr port_no // load base addr     0x2FD  0x3FD
  445.   asm  mov  AL,byte ptr c       //
  446.   asm  out  DX,AL               // transmit byte... channel should be clear
  447.   asm  add  DX,5                //
  448. xempty2:                        //
  449.   asm  sub  DX,5                //
  450.   asm  in   AL,DX               // clr rcv flag (XF sumcheck, noise etc..)
  451.   asm  add  DX,5                // check LINE_STATUS  0x2FD  0x3FD (+5)
  452.   asm  in   AL,DX               //
  453.   asm  and  AL,060h             // wait for DXR and XSR to empty
  454.   asm  cmp  AL,060h             //
  455.   asm  jne  xempty2             //
  456. }
  457. /****************************************************************/
  458. /* printerr is a global error for RS232 comm errors             */
  459. /****************************************************************/
  460. int x, y, errnum=0;
  461. void printerr(void)
  462. {
  463.   x = wherex();                 // If a timeout occurs, a TIMEOUT message
  464.   y = wherey();                 // can be written to the screen.
  465.   gotoxy(1,25);                 //
  466.   printf("RCV T/O %d",errnum++);// Error MSG to bottom of screen
  467.   gotoxy(x,y);                  //
  468. }
  469. /****************************************************************/
  470. /* crcv receives a charcter using handshake protocol (safest!)  */
  471. /****************************************************************/
  472. unsigned char crcv(int port_no)
  473. {
  474.   unsigned char c;
  475.   asm  mov  DX,word ptr port_no // load base addr     0x2FD  0x3FD
  476.   asm  mov  AL,0                // synch value
  477.   asm  out  DX,AL               //
  478.   asm  add  DX,5                // check LINE_STATUS  0x2FD  0x3FD (+5)
  479.   asm  mov  BX,4000             // 836 loops is marginal at 4800 baud.
  480. chkst:                          // with 33MHz 486
  481.   asm  sub  bx,1                //
  482.   asm  jz   timerr              //
  483.   asm  in   AL,DX               //
  484.   asm  and  AL,061h             //
  485.   asm  cmp  AL,061h             //
  486.   asm  jne  chkst               // wait for DRR & RSR to fill
  487.   asm  sub  DX,5                //
  488.   asm  in   AL,DX               // RECV a character
  489.   asm  mov  byte ptr c,AL       //
  490.   return(c);                    //
  491. timerr:                         //
  492.   printerr();                   //
  493.   return(-1);                   //
  494. }
  495. /****************************************************/
  496. /* Bcrcv does not perform a DSK xmit/rcv handshake! */
  497. /* IE 2X SPEED!  But be careful!                    */
  498. /****************************************************/
  499. unsigned char Bcrcv(int port_no)
  500. {
  501.   unsigned char c;
  502.   asm  mov  DX,word ptr port_no // RECV a character
  503.   asm  add  DX,5                // check LINE_STATUS  0x2FD  0x3FD (+5)
  504.   asm  mov  BX,4000             // 836 loops is marginal at 4800 baud.
  505. chkst:                          // with 33MHz 486
  506.   asm  sub  bx,1                //
  507.   asm  jz   timerr              //
  508.   asm  in   AL,DX               //
  509.   asm  and  AL,061h             //
  510.   asm  cmp  AL,061h             //
  511.   asm  jne  chkst               // wait for DRR & RSR to fill
  512.   asm  sub  DX,5                //
  513.   asm  in   AL,DX               //
  514.   asm  mov  byte ptr c,AL       //
  515.   return(c);                    //
  516. timerr:                         //
  517.   printerr();                   //
  518.   return(-1);                   //
  519. }
  520.